package com.siecom.framework.device;

import android.bluetooth.BluetoothDevice;
import android.content.Context;
import android.os.Binder;
import android.os.Bundle;
import android.os.Handler;
import android.text.TextUtils;
import android.util.Log;

import com.siecom.algorithm.sm.SMUtil;
import com.siecom.framework.appinterface.APDU_RESP;
import com.siecom.framework.appinterface.APDU_SEND;
import com.siecom.framework.appinterface.Api;
import com.siecom.framework.channel.ChannelInstance;
import com.siecom.framework.constconfig.Config;
import com.siecom.framework.constconfig.ErrorDefine;
import com.siecom.framework.listen.DeviceConStatusListen;
import com.siecom.framework.listen.FingerPrintListen;
import com.siecom.framework.module.BankCardModule;
import com.siecom.framework.module.EmvOptions;
import com.siecom.framework.module.FingerPrintModule;
import com.siecom.framework.module.KeyBroadOption;
import com.siecom.framework.module.SystemModule;
import com.siecom.tools.ByteTool;
import com.siecom.tools.EncryptUnit;
import com.siecom.tools.LogUtil;
import com.siecom.tools.SingletonThreadPool;
import com.siecom.tools.Timer;

import java.util.List;
import java.util.UUID;
import java.util.concurrent.ExecutorService;

/**
 * Created by zhq on 2015/12/10.
 */
public class SiecomDevice {
    private static final String TAG = SiecomDevice.class.getSimpleName();
    private static SiecomTaskQueue queue = SiecomTaskQueue.getInstance();
    private static ExecutorService threadPool = SingletonThreadPool.getInstance();

    public static void getPin(int keyIndex,String cardNo,String amount,int timeOut,byte maxLen,byte encryptType,SiecomTask.TaskCallback taskCallback){
        getPin(keyIndex, cardNo, amount, timeOut,(byte) 0x04, maxLen, encryptType,1, taskCallback);
    }

    public static void getPin(int keyIndex,String cardNo,String amount,
                              int timeOut,byte minLen,byte maxLen,byte encryptType,int inputTimes,
                              SiecomTask.TaskCallback taskCallback){
        if(TextUtils.isEmpty(cardNo)){
            cardNo = "000000000000";
        }
        SiecomTask task = new SiecomTask(SiecomTask.Operate.GET_PIN,taskCallback);
        KeyBroadOption unit = new KeyBroadOption();
        unit.setMaxLen(maxLen);
        unit.setMinLen(minLen);
        unit.setStartNum(inputTimes);
        unit.cardNo = cardNo;// 卡号
        unit.iAmount = amount;// 金额1.0元要这样000001.00，就是要满6位,不显示就不用设置
        unit.setMode(encryptType);// 00为x9.8加密,明文输入使用0x03
        unit.setMainKeyNo(keyIndex);// 使用哪组密钥加密，这里以主密钥的序列号为准
        unit.setTimeOut(timeOut);
        task.setParams(unit);
        queue.addTask(task);

    }
    
    public static void fingerImg(FingerPrintListen listen) {

		FingerPrintModule module = FingerPrintModule.getInstance();
		module.setCallback(listen);
		module.fingerImg();

	}
    
    public static void inputWorkKey(int keyIndex,int mainKeyIndex,byte[] keyData, SiecomTask.TaskCallback taskCallback){
        SiecomTask task = new SiecomTask(SiecomTask.Operate.INPUT_WORK_KEY,taskCallback);
        KeyBroadOption unit = new KeyBroadOption();
        unit.setType(KeyBroadOption.WORKKEY);// 携带的是工作密钥
        unit.setkeyData(keyData);// 密钥的内容
        unit.setMainKeyNo(mainKeyIndex);// 对应使用的主密钥的编码为0;
        unit.setWorkKeyNo(keyIndex);// 工作密钥的编码为0
        unit.setMode((byte) 0x00);// 0x00MK解密，0x01MK加密，0x02明文，一般使用0x00
        task.setParams(unit);
        queue.addTask(task);

    }

    public static void inputSM4Key(int keyIndex,int mainKeyIndex,byte[] keyData, SiecomTask.TaskCallback taskCallback){
        SiecomTask task = new SiecomTask(SiecomTask.Operate.INPUT_WORK_KEY,taskCallback);
        KeyBroadOption unit = new KeyBroadOption();
        unit.setType(KeyBroadOption.WORKKEY);// 携带的是工作密钥
        unit.setkeyData(keyData);// 密钥的内容
        unit.setMainKeyNo(mainKeyIndex);// 对应使用的主密钥的编码为0;
        unit.setWorkKeyNo(keyIndex);// 工作密钥的编码为0
        unit.setMode((byte) 0x02);// 0x00MK解密，0x01MK加密，0x02明文，一般使用0x00
        task.setParams(unit);
        queue.addTask(task);

    }

    /**
     * 获取SM2公钥
     * @param callback
     */
    public static void getSM2NewKeyPairPublicKey( final SiecomTask.TaskCallback callback){
        new Thread(new Runnable() {
            @Override
            public void run() {
                Bundle bundle = new Bundle();
                int ret = Api.getApi().NewSM2KeyPair(0x01,0x01,0x00);
                if(ret != 0){
                    bundle.putString(ErrorDefine.code,"-1002");
                    bundle.putString(ErrorDefine.message,"sm2 new key pair failed");
                    callback.onError(bundle);
                    return;
                }
                byte[] dataIn = new byte[0];
                byte[] dataOut = new byte[64];
                ret = Api.getApi().UpdateSM2Key((byte) 0x01,(byte)0x01,(byte)0x00,0x00,dataIn,dataOut);
                if(ret == 0){
                    bundle.putString("data",ByteTool.byte2hex(dataOut));
                    callback.onSucceed(bundle);
                }else {
                    bundle.putString(ErrorDefine.code,"-1003");
                    bundle.putString(ErrorDefine.message,"sm2 get PubKey failed");
                    callback.onError(bundle);
                }
            }
        }).start();

    }

    //SM2获取公钥，加载私钥 加载公钥
    public static void inputSM2Key(int keyIndex,int mainKeyIndex,String keyData, SiecomTask.TaskCallback taskCallback){
        if(keyData.length() != 128){
            LogUtil.e("SiecomDevice","传入的公钥位数不对");
            return;
        }
        SiecomTask task = new SiecomTask(SiecomTask.Operate.INPUT_SM2_KEY,taskCallback);
        KeyBroadOption unit = new KeyBroadOption();
        unit.setType(KeyBroadOption.SM2KEY);// 携带的是工作密钥
        unit.setkeyData(ByteTool.hexStr2Bytes(keyData));// 密钥的内容
        unit.setMainKeyNo(mainKeyIndex);// 对应使用的主密钥的编码为0;
        unit.setWorkKeyNo(keyIndex);// 工作密钥的编码为0
        unit.setMode((byte) 0x02);// 0: 获取公钥，1：加载私钥，2：加载公钥
        task.setParams(unit);
        queue.addTask(task);

    }
    /**
     * 随机生成一个主密钥,并返回用公钥加密的后的密文
     * @param type 0: c1c2c3    1: c1c3c2
     *
     */
    public static void sm2EnDecryptMainKey(int keyIndex,int type,SiecomTask.TaskCallback taskCallback){
        String r = getRandom32();
        sm2EnDecryptMainKey(keyIndex,type,r,taskCallback);
    }


    /**
     * //SM2 加密 并写入主密钥
     * @param keyIndex
     * @param type 0: c1c2c3    1: c1c3c2
     * @param keyData
     * @param taskCallback
     */
    public static void sm2EnDecryptMainKey(int keyIndex,int type,String keyData,SiecomTask.TaskCallback taskCallback){
        SiecomTask task = new SiecomTask(SiecomTask.Operate.SM2_EN_DECRYPT,taskCallback);
        KeyBroadOption unit = new KeyBroadOption();
        unit.setkeyData(ByteTool.hexStr2Bytes(keyData));// 密钥的内容
        unit.setMainKeyNo(keyIndex);// 对应使用的主密钥的编码为0;
        unit.setMode((byte) 0x01);// 0: 解密，1：加密
        unit.setType(type);// 0: c1c2c3    1: c1c3c2
        task.setParams(unit);
        queue.addTask(task);
    }

    //SM2 解密 写入主密钥
    /**
     *
     * @param keyIndex
     * @param type  0: c1c2c3    1: c1c3c2
     * @param keyData
     * @param mode 0: 解密，1：加密
     * @param taskCallback
     */
    public static void sm2EnDecryptMainKey(int keyIndex,int type,String keyData,int mode ,SiecomTask.TaskCallback taskCallback){
        SiecomTask task = new SiecomTask(SiecomTask.Operate.SM2_EN_DECRYPT,taskCallback);
        KeyBroadOption unit = new KeyBroadOption();
        unit.setkeyData(ByteTool.hexStr2Bytes(keyData));// 密钥的内容
        unit.setMainKeyNo(keyIndex);// 对应使用的主密钥的编码为0;
        unit.setMode((byte) mode);// 0: 解密，1：加密
        unit.setType(type);// 0: c1c2c3    1: c1c3c2
        task.setParams(unit);
        queue.addTask(task);
    }

    /**
     * 用传入的公钥 加密随机秘钥 并写入主密钥
     * @param pubKey 传入的主密钥
     * @param data 随机主密钥
     * @param keyIndex 秘钥索引
     * @param taskCallback
     */
    public static void sm2EnDecryptMainKey(String pubKey, String data, int keyIndex, final SiecomTask.TaskCallback taskCallback){
        Bundle bundle = new Bundle();
        if (pubKey.length() != 128 && data.length() != 32){
            bundle.putString("msg","公钥或加密数据位数不对");
            bundle.putInt("ret",-1);
            if(taskCallback != null)
            taskCallback.onError(bundle);
            return;
        }
        String pubX = pubKey.substring(0,64);
        String pubY = pubKey.substring(64);
        LogUtil.e(TAG,"x="+ pubX + "--y=" + pubY);
        String result = SMUtil.SM2PubEncrypt(ByteTool.hexStr2Bytes(data),pubX,pubY,2);
        result = result.toUpperCase();
        LogUtil.e(TAG,"加密结果：" + result);
        if(result.length() == 224){
            final String finalResult = result;
            inputMainKey(keyIndex, ByteTool.hexStr2Bytes(data), new SiecomTask.TaskCallback() {
                @Override
                public void onStart(Bundle bundle) {
                    if(taskCallback != null)
                        taskCallback.onStart(bundle);
                }

                @Override
                public void onSucceed(Bundle bundle) {
                    String check = bundle.getString("data");
                    bundle.putString("msg","加密成功");
                    bundle.putString("data", finalResult);
                    bundle.putString("check",check);
                    bundle.putInt("ret",0);
                    if(taskCallback != null)
                        taskCallback.onSucceed(bundle);
                }

                @Override
                public void onError(Bundle bundle) {
                    bundle.putString("msg","主密钥写入错误");
                    bundle.putInt("ret",-3);
                    if(taskCallback != null)
                        taskCallback.onError(bundle);
                }
            });
        }else {
            bundle.putString("msg","加密错误");
            bundle.putInt("ret",-2);
            if(taskCallback != null)
            taskCallback.onError(bundle);
        }

    }

    /**
     * 用传入的RSA公钥 加密随机秘钥 并写入主密钥
     * @param pubKey 传入的主密钥
     * @param data 随机主密钥
     * @param keyIndex 秘钥索引
     * @param taskCallback
     */
    public static void rsaEnDecryptMainKey(String pubKey, String data, int keyIndex, final SiecomTask.TaskCallback taskCallback) {
        Bundle bundle = new Bundle();
//        if (pubKey.length() != 128 && data.length() != 32) {
//            bundle.putString("msg", "公钥或加密数据位数不对");
//            bundle.putInt("ret", -1);
//            if (taskCallback != null)
//                taskCallback.onError(bundle);
//            return;
//        }
        try {
           final byte result[] =  EncryptUnit.encryptByPublicKey(ByteTool.hexStr2Bytes(data),ByteTool.hexStr2Bytes(pubKey));
            inputMainKey(keyIndex, ByteTool.hexStr2Bytes(data), new SiecomTask.TaskCallback() {
                @Override
                public void onStart(Bundle bundle) {
                    if(taskCallback != null)
                        taskCallback.onStart(bundle);
                }

                @Override
                public void onSucceed(Bundle bundle) {
                    String check = bundle.getString("data");
                    bundle.putString("msg","加密成功");
                    bundle.putString("data", ByteTool.byte2hex(result));
                    bundle.putString("check",check);
                    bundle.putInt("ret",0);
                    if(taskCallback != null)
                        taskCallback.onSucceed(bundle);
                }

                @Override
                public void onError(Bundle bundle) {
                    bundle.putString("msg","主密钥写入错误");
                    bundle.putInt("ret",-3);
                    if(taskCallback != null)
                        taskCallback.onError(bundle);
                }
            });
        } catch (Exception e) {
            e.printStackTrace();
        }


    }

    public static String sm2Decrypt(String priKey,String data,int mode){
       byte[] bytes = SMUtil.SM2PrvDecrypt(priKey,data,mode);
       String result = ByteTool.byte2hex(bytes);
       LogUtil.e(TAG,"解密结果：" + result);
       return result;
    }

    /**
     * SM4加解密
     * @param keyIndex 密钥索引 0-9
     * @param type 0 - ECB   1 - CBC
     * @param mode 0 解密  1 加密
     * @param inData 要加密的数据
     * @param outData 得到的数据
     * @return  0 成功 其他 失败
     */
    public static int sm4EnDecryptData(int keyIndex, int type, int mode, byte[] inData, List<byte[]> outData){
        Api api = new Api();
        int channel = 1; // SIM 1卡座
        int voltage = 1; //1 5V
//        int keyIndex = 0; // 密钥索引（编号）0-9
//        int type = 0;  // 0 - ECB   1 - CBC
//        int mode = 0; // 0 解密  1 加密
        int ret = api.SM4EncryptDecode(channel,voltage,keyIndex,type,mode,inData,outData);
        return ret;
    }

    /**
     * MAC 计算
     * @param keyNo 密钥索引 0-9 国际   10-19国密
     * @param mode 计算模式 0-3
     * @param inData 要计算的数据
     * @param outData 计算出来的数据
     * @return
     */
    public static int getMac(int keyNo,int mode,byte[] inData,byte[] outData){
        if(inData.length > 1024){
            return -1;
        }
        return Api.getApi().Pci_GetMac((byte) keyNo,(byte)mode,inData,outData);
    }

    /**
     *
     * @param cmdData CLA INS P1 P2
     * @param send 要发送的数据
     * @param Lc 发送数据的长度 一般0-512
     * @param Le 期望返回的数据长度 256表示有多少返回多少
     * @param outData 返回的数据
     * @return 0 成功
     */
    public static int apdu(String cmdData,String send,short Lc,short Le,byte[] outData){
        byte[]  cmd = ByteTool.hexStr2Bytes(cmdData);
        byte[] sendData;
        if(!TextUtils.isEmpty(send) && send.length() > 0){
            sendData = ByteTool.hexStr2Bytes(send);
        }else {
            sendData = new byte[0];
        }
//        short Lc = 0x00;
//        short Le = 04;

        APDU_SEND ApduSend = new APDU_SEND(cmd, Lc, sendData, Le);
        APDU_RESP ApduResp = new APDU_RESP();
        Api api = new Api();
        int ret = api.Icc_Command((byte) 0x00, ApduSend, ApduResp);
        if (ret != 0) {
            Log.e("ret", " ret = " + ret);
            return ret;
        }
        byte[] bf = new byte[ApduResp.LenOut];
        System.arraycopy(ApduResp.DataOut, 0, bf, 0, ApduResp.LenOut);
        Log.e("bf5", ByteTool.byte2hex(bf)+"===len:"+bf.length);
        Log.e("SWA", ByteTool.byteToHexString(ApduResp.SWA));
        Log.e("SWB", ByteTool.byteToHexString(ApduResp.SWB));
        if(ApduResp.SWA!=(byte)0x90||ApduResp.SWB!=(byte)0x00){
            return -904;
        }
        System.arraycopy(bf, 0, outData, 0, ApduResp.LenOut);
        return 0;
    }
//    public static String sm4ChangeMainKey(String key,String data,int index,SiecomTask.TaskCallback taskCallback){
//        String plantText = SMUtil.SM4DecryptECB(data,key);
//        inputMainKey(index,ByteTool.hexStr2Bytes(plantText),taskCallback);
//        return plantText;
//    }

    public int getATR(byte[] ATR){
        return Api.getApi().Icc_Open((byte) 0x00,(byte) 01,ATR);
    }

    // 8位  16个字符
    public static String getRandom(){
        Api api = new Api();
        byte r[] = new byte[16];
        int ret = api.getRandomKeyNum(r);
        Log.e("","getRandom iret=="+ ret);
        if(ret == 0){
            return ByteTool.byte2hex(r);
        }else {
            return "";
        }
    }
    public static String getRandom32(){
        UUID uuid = UUID.randomUUID();
        String str = uuid.toString();
        // 去掉"-"符号
        StringBuffer temp = new StringBuffer();
        temp.append(str.substring(0, 8))
                .append(str.substring(9, 13))
                .append(str.substring(14, 18))
                .append(str.substring(19, 23))
                .append(str.substring(24));
        return temp.toString();
    }


    public static void inputMainKey(int keyIndex,byte[] keyData,SiecomTask.TaskCallback taskCallback){
        SiecomTask task = new SiecomTask(SiecomTask.Operate.INPUT_MAIN_KEY,taskCallback);

        KeyBroadOption unit = new KeyBroadOption();
        unit.setType(KeyBroadOption.MAINKEY);// 携带的是主密钥
        unit.setkeyData(keyData);// 密钥的内容
        unit.setMainKeyNo(keyIndex);// 主密钥的编码;

        task.setParams(unit);
        queue.addTask(task);

    }

    public static void changeMainKey(String mKey,byte[] checkValue, byte keyIndex){
        changeMainKey(mKey,checkValue,keyIndex,null);
    }
    public static void changeMainKey(String mKey,byte[] checkValue, byte keyIndex,SiecomTask.TaskCallback taskCallback){
        Api api = new Api();
        int ret = api.UpdateMkey((byte) 0x0A,mKey,checkValue,keyIndex);
        LogUtil.e("changeMainKey","ret=" + ret);
        if(taskCallback != null){
            Bundle bundle = new Bundle();
            bundle.putInt("ret",ret);
            if(ret == 0){
                bundle.putString("data",ByteTool.byte2hex(checkValue));
                taskCallback.onSucceed(bundle);
            }else {
                taskCallback.onError(bundle);
            }
        }
    }

    public static void deviceConnStatusChange( DeviceConStatusListen statusListen ){

        ChannelInstance.setStatusListen(statusListen);
    }

    public static void cancelLastTask(boolean isConnected){
        queue.cancelCurrentTask(isConnected);
    }

    public static void connectToBtDevice(final BluetoothDevice device, SiecomTask.TaskCallback taskCallback){
        SiecomTask task = new SiecomTask(SiecomTask.Operate.CONNECT_BT,taskCallback);
        task.setParams(device);
        queue.addTask(task);
    }
    public static void disConnectBtDevice(){
        ChannelInstance.destroy();
    }
    public static void ReadIdentity(boolean withFinger, SiecomTask.TaskCallback taskCallback, int timeOut){
        SiecomTask task = new SiecomTask(SiecomTask.Operate.READ_IDENTITY,taskCallback);
        task.setParams(withFinger);
        task.setTimeOut(timeOut);
        queue.addTask(task);
    }
    public static void ReadIdentity(Context mContext,boolean withFinger, SiecomTask.TaskCallback taskCallback, int timeOut){
        SiecomTask task = new SiecomTask(SiecomTask.Operate.READ_IDENTITY,taskCallback);
        task.setParams(withFinger);
        task.setTimeOut(timeOut);
        task.setmContext(mContext);
        queue.addTask(task);
    }
    public static void ReadFinger(int fingerPrintType,  SiecomTask.TaskCallback taskCallback,int timeOut){
        SiecomTask task = new SiecomTask(SiecomTask.Operate.FINGER_PRINT,taskCallback);
        task.setParams(fingerPrintType);
        task.setTimeOut(timeOut);
        queue.addTask(task);
    }
    public static void RegistrationFinger(int fingerPrintType,  SiecomTask.TaskCallback taskCallback,int timeOut){
        SiecomTask task = new SiecomTask(SiecomTask.Operate.REGISTRATION_FINGER,taskCallback);
        task.setParams(fingerPrintType);
        task.setTimeOut(timeOut);
        queue.addTask(task);
    }
    public static void ReadFingerbitmap(SiecomTask.TaskCallback taskCallback,int timeOut){
    	SiecomTask task = new SiecomTask(SiecomTask.Operate.FINGERIMG,taskCallback);
    	task.setTimeOut(timeOut);
    	queue.addTask(task);
    }

    public static void ReadCardLog(int cardType,int logType,SiecomTask.TaskCallback taskCallback,int timeOut){
        //  BankCardModule.getInstance().ONLY_CARD = 0;
        SiecomTask.Operate operate = null;
        switch (logType){
            case 0:
                operate = SiecomTask.Operate.READ_LOG;
                break;
            case 1:
                operate = SiecomTask.Operate.READ_LOAD_LOG;
                break;
        }
        SiecomTask task = new SiecomTask(operate,taskCallback);
        task.setParams(cardType);
        task.setTimeOut(timeOut);
        queue.addTask(task);
    }

    public static void ReadBankCard(int cardType,EmvOptions options,SiecomTask.TaskCallback taskCallback,int timeOut){
       //  BankCardModule.getInstance().ONLY_CARD = 0;
        LogUtil.e(TAG,"ReadBankCard  cardtype == " + cardType);
        SiecomTask.Operate operate = null;
        switch (cardType){
            case BankCardModule.IC_CARD:
                operate = SiecomTask.Operate.READ_IC_CARD;
                break;
            case BankCardModule.MSR_CARD:
                operate = SiecomTask.Operate.READ_MSR_CARD;
                break;
            case BankCardModule.PIC_CARD:
                operate = SiecomTask.Operate.READ_PIC_CARD;
                break;
            case BankCardModule.AUTO_FIND:
                operate = SiecomTask.Operate.READ_AUTO_FIND;
                break;
        }
        SiecomTask task = new SiecomTask(operate,taskCallback);
        task.setParams(options);
        task.setTimeOut(timeOut);
        queue.addTask(task);
    }


    public static void shutDownCard(){

        Runnable r = new Runnable() {
            @Override
            public void run() {

                BankCardModule.getInstance().shutDownCard();
            }
        };
        threadPool.submit(r);

    }
    public static int  SyncARPCExecuteScript(int ICType, String ARPC, String Script,byte[] ScriptResult, byte[] TC){

        return BankCardModule.getInstance().ARPCExecuteScript(ICType,ARPC,Script,ScriptResult,TC);

    }

    public static int SyncGetLog(int ICType, byte[] tlog, int[] length){

        return  BankCardModule.getInstance().GetLog(ICType, tlog, length);
    }

    public static int SyncGetLoadLog(int ICType, byte[] tlog, int[] length){

        return  BankCardModule.getInstance().GetLoadLog(ICType, tlog, length);
    }


    public static int SyncWriteCodeName(String codeName){

        return SystemModule.writeCodeName(codeName);
    }
    public static String SyncReadCodeName(){

        return SystemModule.readCodeName();
    }

    public static int SysWriteSNTwo(String two){
        return SystemModule.setDeviceNoTwo(two);
    }
    public static  String SysReadSNTwo(){
        return SystemModule.getDeviceNoTwo();
    }

    public static String SyncReadSerialNo(){

        return SystemModule.readSerialNo();
    }
    public static String SyncReadSerialNoHN(){
        return SystemModule.readSerialNoHN();
    }

    public static void beep(){

           SystemModule.beep();
    }
    public static String SyncReadFwVersion(){
        return SystemModule.readFwVersion();
    }
    public static String SyncReadRTC(){
        return SystemModule.getRTC();
    }
    public static int SyncTestPsam(byte slot){

        return SystemModule.testPsamSlot(slot);
    }
    public static int SyncValidateARPC(byte[] content){

        return BankCardModule.getInstance().validateARPC(content);
    }
    public static String SyncReadFingerVer(){

        return SystemModule.getInstance().readFingerVer();
    }

    public static String getSdkVersion(){
        return Config.SDK_VERSION;
    }

    /**
     * 明文获取键盘输入
     */
    public static String getKeyValue(){
        int key_value;
        Api.getApi().Kb_Flush();
        StringBuffer sb = new StringBuffer();
        while (true){
            if(Api.getApi().Kb_Check() == 0){
                key_value =  Api.getApi().Kb_Value();
                if(key_value == 0x1B ||key_value == 13){  //0x1B是取消  0x0D是确认
                    LogUtil.e(TAG,"输入终止：" + key_value);
                    if(key_value == 0x1b){
                        sb = new StringBuffer();
                    }
                    break;
                }else if(key_value >=0x30 && key_value <=0x39){
                    String in = new String(new byte[]{(byte) key_value});
                    sb.append(in);
                    LogUtil.e(TAG,"输入了:" + in);
                }
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
        return sb.toString();
    }
    //清除密钥
    public static int  clearKeys(){
        return Api.getApi().ClearKeys();
    }
    private static Handler handler = new Handler();

    /**
     *
     * @param in 写入的数据
     * @param type  1 TEXT 类型  2 URI类型
     * @param callback 回调
     * @param timeout 超时时间 ms
     */
    public static void writeNFCData(final String in, final int type, final SiecomTask.TaskCallback callback, final int timeout){
        SingletonThreadPool.getInstance().submit(new Runnable() {
            @Override
            public void run() {
                int ret = -1;
                try {
                    ret = Api.getApi().NFC_Open();
                    if(ret != 0){
                        Bundle bundle = new Bundle();
                        bundle.putInt("code",1);
                        bundle.putString("message","设备连接断开");
                        callback.onError(bundle);
                        return;
                    }
                    if(type == 2){
                        ret = Api.getApi().NFCWriteData(in.getBytes(),timeout);
                    }else {
                        ret = Api.getApi().NFCWriteTxtData(in.getBytes(),timeout);
                    }
                    Log.e(TAG,"NFCWriteData ret == " + ret);
                    Bundle bundle = new Bundle();
                    if(ret == 0){
                        bundle.putInt("code",0);
                        bundle.putString("message","写入数据成功");
                        deliverResult(bundle,EnmuResult.SUCCESS,callback);

                    } else if(ret == -3001){
                        bundle.putInt("code",3);
                        bundle.putString("message","写入数据超时");
                        deliverResult(bundle,EnmuResult.ERROR,callback);

                    }else {
                        bundle.putInt("code",2);
                        bundle.putString("message","写入数据失败");
                        deliverResult(bundle,EnmuResult.ERROR,callback);
                    }
                }catch (Exception e){
                    e.printStackTrace();
                    Bundle bundle = new Bundle();
                    bundle.putInt("code",-2);
                    bundle.putString("message","in message error " + e.getMessage());
                    deliverResult(bundle,EnmuResult.ERROR,callback);
                }finally {
                    Api.getApi().NFC_Close();
                }
            }
        });
    }
    public enum EnmuResult{
        SUCCESS,
        ERROR
    }
    private static void deliverResult(final Bundle bundle, final EnmuResult result, final SiecomTask.TaskCallback callback){

        handler.post(new Runnable() {
            @Override
            public void run() {
                switch (result){
                    case SUCCESS:
                        callback.onSucceed(bundle);
                        break;
                    case ERROR:
                        callback.onError(bundle);
                        break;
                }
            }
        });
    }

    public static void readNFCdata(final SiecomTask.TaskCallback callback, final int timeOutMs){

        SingletonThreadPool.getInstance().submit(new Runnable() {
            @Override
            public void run() {
                int timeOut = timeOutMs;
                byte data[] = new byte[256];
                int ret = Api.getApi().NFC_Open();
                if(ret != 0){
                    Bundle bundle = new Bundle();
                    bundle.putInt("code",1);
                    bundle.putString("message","设备连接断开");
                    deliverResult(bundle,EnmuResult.ERROR,callback);
                    return ;
                }
                if(timeOutMs < 10*1000){
                    timeOut = 10*1000;
                }

                Bundle bundle = new Bundle();
                int[] len = new int[1];
                try{
                    Timer timer = new Timer(timeOutMs);
                    timer.start();
                    while (true){
                        if(timer.timeOut()){
                            bundle.putInt("code",3);
                            bundle.putString("message","读标签超时");
                            deliverResult(bundle,EnmuResult.ERROR,callback);
                            break;
                        }
                        ret = Api.getApi().NFCReadData(data,len,10 * 1000);
                        if(ret == 0 && len[0] > 0){
                            byte[] out = new byte[len[0]];
                            System.arraycopy(data,0,out,0,len[0]);

                            bundle.putInt("code",0);
                            bundle.putByteArray("message",out);
                            bundle.putString("data",ByteTool.byte2hex(out));
                            deliverResult(bundle,EnmuResult.SUCCESS,callback);
                            break ;
                        }else if (ret == -3001){
                            bundle.putInt("code",3);
                            bundle.putString("message","读标签超时");
                            deliverResult(bundle,EnmuResult.ERROR,callback);
                            break;
                        }else {
                            bundle.putInt("code",2);
                            bundle.putString("message","读标签失败");
                            deliverResult(bundle,EnmuResult.ERROR,callback);
                            break;
                        }

                    }
                }finally {
                    Api.getApi().NFC_Close();
                }
            }
        });

    }



}
